import { FFmpegTask } from './base'
import * as fs from 'fs'
import * as path from 'path'
import * as os from 'os'

/**
 * 视频拼接选项
 */
export interface ConcatOptions {
  inputs: string[] // 输入文件列表
  output: string
  reEncode?: boolean // 是否重新编码（false时直接合并，速度快但要求格式一致）
}

/**
 * 视频分割选项
 */
export interface SplitOptions {
  input: string
  output: string
  startTime: string | number // 开始时间 '00:01:30' 或 90(秒)
  duration?: string | number // 持续时长 '00:00:30' 或 30(秒)
  endTime?: string | number // 结束时间（与duration二选一）
}

/**
 * 视频旋转选项
 */
export interface RotateOptions {
  input: string
  output: string
  angle: 90 | 180 | 270 // 旋转角度
  flip?: 'horizontal' | 'vertical' // 翻转
}

/**
 * 视频裁剪选项
 */
export interface CropOptions {
  input: string
  output: string
  width: number
  height: number
  x?: number // 起始 X 坐标
  y?: number // 起始 Y 坐标
}

/**
 * 视频倍速选项
 */
export interface SpeedOptions {
  input: string
  output: string
  speed: number // 倍速 0.5-2.0
}

/**
 * 拼接视频
 */
export function concatVideos(options: ConcatOptions): FFmpegTask {
  if (options.reEncode) {
    // 重新编码方式（兼容性好）
    const inputs: string[] = []
    const filterInputs: string[] = []

    options.inputs.forEach((file, index) => {
      inputs.push('-i', file)
      filterInputs.push(`[${index}:v:0][${index}:a:0]`)
    })

    const filter = `${filterInputs.join('')}concat=n=${options.inputs.length}:v=1:a=1[outv][outa]`

    const args = [
      ...inputs,
      '-y',
      '-filter_complex',
      filter,
      '-map',
      '[outv]',
      '-map',
      '[outa]',
      options.output
    ]

    return new FFmpegTask(args, options.inputs[0])
  } else {
    // 直接合并方式（速度快但要求相同编码格式）
    const listFile = path.join(os.tmpdir(), `concat_${Date.now()}.txt`)
    const content = options.inputs.map((f) => `file '${f}'`).join('\n')
    fs.writeFileSync(listFile, content)

    const args = ['-f', 'concat', '-safe', '0', '-i', listFile, '-y', '-c', 'copy', options.output]

    const task = new FFmpegTask(args, options.inputs[0])

    // 任务结束后删除临时文件
    task.on('end', () => fs.unlinkSync(listFile))
    task.on('error', () => {
      if (fs.existsSync(listFile)) fs.unlinkSync(listFile)
    })

    return task
  }
}

/**
 * 分割视频
 */
export function splitVideo(options: SplitOptions): FFmpegTask {
  const args: string[] = ['-i', options.input, '-y']

  // 开始时间
  if (options.startTime) {
    const start = typeof options.startTime === 'number' ? options.startTime : options.startTime
    args.push('-ss', String(start))
  }

  // 持续时长或结束时间
  if (options.duration) {
    const duration = typeof options.duration === 'number' ? options.duration : options.duration
    args.push('-t', String(duration))
  } else if (options.endTime) {
    const end = typeof options.endTime === 'number' ? options.endTime : options.endTime
    args.push('-to', String(end))
  }

  // 直接复制流，无需重新编码
  args.push('-c', 'copy', options.output)

  return new FFmpegTask(args, options.input)
}

/**
 * 旋转/翻转视频
 */
export function rotateVideo(options: RotateOptions): FFmpegTask {
  let filter = ''

  // 旋转
  const transposeMap: Record<number, string> = {
    90: '1', // 顺时针90度
    180: '2,transpose=2', // 180度 = 两次90度
    270: '2' // 逆时针90度 = 顺时针270度
  }

  if (options.angle) {
    filter = `transpose=${transposeMap[options.angle]}`
  }

  // 翻转
  if (options.flip === 'horizontal') {
    filter = filter ? `${filter},hflip` : 'hflip'
  } else if (options.flip === 'vertical') {
    filter = filter ? `${filter},vflip` : 'vflip'
  }

  const args: string[] = ['-i', options.input, '-y', '-vf', filter, '-c:a', 'copy', options.output]

  return new FFmpegTask(args, options.input)
}

/**
 * 裁剪视频
 */
export function cropVideo(options: CropOptions): FFmpegTask {
  const x = options.x || 0
  const y = options.y || 0
  const filter = `crop=${options.width}:${options.height}:${x}:${y}`

  const args: string[] = ['-i', options.input, '-y', '-vf', filter, '-c:a', 'copy', options.output]

  return new FFmpegTask(args, options.input)
}

/**
 * 调整视频速度
 */
export function changeSpeed(options: SpeedOptions): FFmpegTask {
  // 视频速度
  const videoSpeed = 1 / options.speed
  // 音频速度
  const audioSpeed = options.speed

  const filter = `[0:v]setpts=${videoSpeed}*PTS[v];[0:a]atempo=${audioSpeed}[a]`

  const args: string[] = [
    '-i',
    options.input,
    '-y',
    '-filter_complex',
    filter,
    '-map',
    '[v]',
    '-map',
    '[a]',
    options.output
  ]

  return new FFmpegTask(args, options.input)
}
